﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using Javavaj.iHunter;
using Javavaj.iHunter.Core;
using Javavaj.iHunter.UI;
namespace Javavaj.iHunter.UI
{
    delegate void Task();
  
    internal partial class MainForm : DevComponents.DotNetBar.Office2007RibbonForm
    {
        class MessageListPubTimeSorter : IComparer<ListViewItem>, System.Collections.IComparer
        {
            public MessageListPubTimeSorter()
            {
                
            }
            #region IComparer<ListViewItem> 成员

            public int Compare(ListViewItem x, ListViewItem y)
            {
                if (x == null && y == null)
                    return 0;
                if (x == null && y != null)
                    return 1;
                if (x != null && y == null)
                    return -1;
                return DateTime.Compare(DateTime.Parse(x.SubItems["PubTime"].Text), DateTime.Parse(y.SubItems["PubTime"].Text));
            }

            #endregion

            #region IComparer 成员

            public int Compare(object x, object y)
            {

                return Compare(x as ListViewItem, y as ListViewItem);
                
            }

            #endregion
        }

        PluginManagementForm pluginManagementDialog;
        Queue<Task> tasks;
        IMessage currentMessage = null;
        private static IMessage[] emptyMessageList = new IMessage[0];
        IMessage[] currentMessageList = emptyMessageList;
        int animationIndex = 0;
        List<ListViewItem> pendingRemoveItems = null;
        bool autoDownload;
        long autoDownloadSizeLimit;
        MessageViewForm messageViewer = null;
        private string idleText ;
        public Javavaj.iHunter.Core.ClientCore ClientCore
        {
            get;
            set;
        }

        public MainForm()
        {
            InitializeComponent();
        }
        public MainForm(ClientCore core)
        {
            idleText = "No background job.".Translate();
            ClientCore = core;
            messageViewer = new MessageViewForm();
            messageViewer.AttachmentLinkClicked +=new AttachmentLinkClickedEventHandler(messageViewer_AttachmentLinkClicked);

            InitializeComponent();

        }

        #region Command Actions



        private void commandUpdateAllChannels_Executed(object sender, EventArgs e)
        {
            foreach (var channel in ClientCore.GetChannels())
            {
                IChannel ch = channel;
                PendTask(delegate
                {
                    this.Invoke(new Task(
                        delegate
                        {
                            string str;
                            labelCurrentWork.Text = "Updating channel ".Translate() + "\"" + ch.Title + "\" ...";
                        }));
                     if (!ch.Open())
                     {
                         ShowErrorMessage("Cannot open channal ".Translate() + "\"" + ch.Title + "\".", true);
                         return;
                     }
                     ClientCore.RefreshChannel(ch, ClientCore.GetChannelLastUpdateTime(ch), DateTime.Now, null);
                     ch.Close();
                     ClientCore.SetChannelLastUpdateTime(ch, DateTime.Now);
                     this.Invoke(new Task(
                        delegate
                        {
                            labelCurrentWork.Text = idleText;
                        }));
                     RefreshChannelList();
                });
            }
 
        }

        private void ShowErrorMessage(string message, bool critical)
        {
            this.Invoke(new Task(delegate
               {
                   MessageBox.Show(this,
                     message.Translate(),
                     null, MessageBoxButtons.OK,
                     (critical ? MessageBoxIcon.Error : MessageBoxIcon.Warning)
                     );
                   this.labelCurrentWork.Text = idleText;
               }));
        }

        private void commandUpdateSelectedChannel_Executed(object sender, EventArgs e)
        {
            TreeNode selectedNode = channelsTreeViewNormal.SelectedNode;
            UpdateFolder(selectedNode);
        }

        private void UpdateFolder(TreeNode selectedNode)
        {
            if (selectedNode == null)
                return;

            switch (selectedNode.Level)
            {
                case 0:
                    commandUpdateAllChannels.Execute();
                    break;
                case 1:
                    foreach (TreeNode childNode in selectedNode.Nodes)
                    {
                        IChannel ch = childNode.Tag as IChannel;
                        PendTask(new Task(delegate
                        {
                            this.Invoke(new Task(
                                delegate
                                {
                                    labelCurrentWork.Text = "Updating channel ".Translate() + "\"" + ch.Title + "\" ...";
                                }));
                            if (ch != null)
                            {
                                if (ch.Open())
                                {
                                    ClientCore.RefreshChannel(ch, ClientCore.GetChannelLastUpdateTime(ch), DateTime.Now, null);
                                    ch.Close();
                                    ClientCore.SetChannelLastUpdateTime(ch, DateTime.Now);
                                }
                                else
                                {
                                    ShowErrorMessage("Cannot open channal ".Translate() + "\"" + ch.Title + "\".", true);
                                }
                            }
                            this.Invoke(new Task(
                                delegate
                                {
                                    labelCurrentWork.Text = idleText;
                                }));
                            RefreshChannelList();
                        }));
                    }

                    break;
                case 2:
                    {
                        IChannel ch = selectedNode.Tag as IChannel;
                        PendTask(new Task(delegate
                        {
                            this.Invoke(new Task(
                                delegate
                                {
                                    labelCurrentWork.Text = "Updating channel ".Translate() + "\"" + ch.Title + "\" ...";
                                }));
                            if (ch != null)
                            {
                                if (ch.Open())
                                {
                                    ClientCore.RefreshChannel(ch, ClientCore.GetChannelLastUpdateTime(ch), DateTime.Now, null);
                                    ch.Close();
                                    ClientCore.SetChannelLastUpdateTime(ch, DateTime.Now);
                                }
                                else
                                {
                                    ShowErrorMessage("Cannot open channal ".Translate() + "\"" + ch.Title + "\".", true);
                                }
                            }
                            this.Invoke(new Task(
                                delegate
                                {
                                    labelCurrentWork.Text = idleText;
                                }));
                            RefreshChannelList();
                        }));
                    }
                    break;
                case 3:
                    {
                        IChannel ch = selectedNode.Parent.Tag as IChannel;
                        PendTask(new Task(delegate
                        {
                            this.Invoke(new Task(
                                 delegate
                                 {
                                     labelCurrentWork.Text = "Updating channel ".Translate() + "\"" + ch.Category + "/" + ch.Title + "\" ...";
                                 }));
                            if (ch != null)
                            {
                                if (ch.Open())
                                {
                                    ClientCore.RefreshChannel(ch, ClientCore.GetChannelLastUpdateTime(ch), DateTime.Now, selectedNode.Tag as string);
                                    ch.Close();
                                    ClientCore.SetChannelLastUpdateTime(ch, DateTime.Now);
                                }
                                else
                                {
                                    ShowErrorMessage("Cannot open channal ".Translate() + "\"" + ch.Title + "\".", true);
                                }
                            }
                            this.Invoke(new Task(
                                delegate
                                {
                                    labelCurrentWork.Text = idleText;
                                }));
                            RefreshChannelList();
                        }));

                    }
                    break;
                default:
                    break;
            }

        }

        private void commandReplyMessage_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            IMessage message = ClientCore.GetMessage(currentMessage);
            ClientCore.BeginReply(message);
        }

        private void commandSetSpam_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            IMessage message = ClientCore.GetMessage(currentMessage);
            message.Spam = true;
            currentMessage.Spam = true;
            ClientCore.UpdateMessage(message);
            ClientCore.TrainFilter(message);
            RefreshChannelList();

        }

        private void commandSaveAsXml_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            saveMessageDialog.FilterIndex = 0;
            saveMessageDialog.DefaultExt = "xml";
            saveMessageDialog.FileName = currentMessage.Title;
            if (saveMessageDialog.ShowDialog(this) != DialogResult.OK)
                return;

            string filename = saveMessageDialog.FileName;
            //TODO;
            ClientCore.SaveMessageAsXml(currentMessage, filename);
        }

        private void commandSaveAsWeb_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            saveMessageDialog.FilterIndex = 0;
            saveMessageDialog.DefaultExt = "xml";
            saveMessageDialog.FileName = currentMessage.Title;
            if (saveMessageDialog.ShowDialog(this) != DialogResult.OK)
                return;

            string filename = saveMessageDialog.FileName;
            //TODO;

        }

        private void commandDeleteMessage_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            if (MessageBox.Show(this, "Are you sure to delete this messages?".Translate(), "iHunter".Translate(), MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                return;
            ClientCore.DeleteMessage(currentMessage);
            currentMessage = null;
            RefreshChannelList();
            RefreshMessageView();

        }

        private void commandPrintMessage_Executed(object sender, EventArgs e)
        {
            //TODO
 
        }

   

        private void commandSetUseful_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            IMessage message = ClientCore.GetMessage(currentMessage);
            message.Spam = false;
            currentMessage.Spam = false;
            ClientCore.UpdateMessage(message);
            ClientCore.TrainFilter(message);
            RefreshChannelList();

        }

        private void commandSearch_Executed(object sender, EventArgs e)
        {
            string keyword = null;
            DateTime? startTime = null;
            DateTime? endTime = null;

            if (ribbonSearchKeyword.Text.Length > 0)
                keyword = ribbonSearchKeyword.Text;

            if (ribbonSearchFrom.LockUpdateChecked)
                startTime = ribbonSearchFrom.Value;

            if (ribbonSearchTo.LockUpdateChecked)
                endTime = ribbonSearchTo.Value;

            currentMessageList = ClientCore.Search(keyword, startTime, endTime);

            RefreshMessageList();


        }

        private void commandSetRank_Executed(object sender, EventArgs e)
        {

        }

        private void commandConfigurePlugins_Executed(object sender, EventArgs e)
        {
            pluginManagementDialog = new PluginManagementForm();
            pluginManagementDialog.PluginList = ClientCore.GetPlugins();
            pluginManagementDialog.PluginInstallRequested += new PluginInstallRequestedEventHandler(form_PluginInstallRequested);
            pluginManagementDialog.PluginConfigRequested += new PluginConfigRequestedEventHandler(form_PluginConfigRequested);
            pluginManagementDialog.PluginRemoveRequested += new PluginRemoveRequestedEventHandler(form_PluginRemoveRequested);
            pluginManagementDialog.PluginInfoChanged += new PluginInfoChangedEventHandler(form_PluginInfoChanged);
            pluginManagementDialog.ShowManagementDialog();
            pluginManagementDialog.Dispose();
        }

        private void commandExitApplication_Executed(object sender, EventArgs e)
        {
            timerAutoRefresh.Stop();
            timerRemoveItemDelay.Stop();
            
            ClientCore.Close();
        }

        private void commandApplicationSettings_Executed(object sender, EventArgs e)
        {
            GlobalSettingsForm form = new GlobalSettingsForm();
            form.Settings = ClientCore.GetGlobalSettings();
            if (form.ShowDialog(this) == DialogResult.OK)
                ClientCore.SetGlobalSettings(form.Settings);

            LoadGlobalSettings();
        }

        private void LoadGlobalSettings()
        {
            XmlDocument settings = ClientCore.GetGlobalSettings();
            if (bool.Parse(settings.DocumentElement["AutoUpdate"].InnerText))
            {
                timerAutoRefresh.Interval = (int)TimeSpan.Parse(settings.DocumentElement["AutoUpdateInterval"].InnerText).TotalMilliseconds;
                timerAutoRefresh.Start();
            }
            else
            {
                timerAutoRefresh.Stop();
            }

            autoDownload = bool.Parse(settings.DocumentElement["AutoDownloadFile"].InnerText);

            if (autoDownload)
            {
                autoDownloadSizeLimit = long.Parse(settings.DocumentElement["AutoDownloadSizeLimit"].InnerText);
                if (autoDownloadSizeLimit <= 0)
                    autoDownloadSizeLimit = long.MaxValue;
            }
        }



        private void commandDeleteDatabase_Executed(object sender, EventArgs e)
        {
            DeleteDatabaseForm form = new DeleteDatabaseForm();
            if (form.ShowDialog() != DialogResult.OK)
                return;

            
            if (MessageBox.Show(
                    this,
                    "Are you sure to delete the database?".Translate(),
                    "iHunter".Translate(), 
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question
                    ) 
                != DialogResult.Yes)
                return;
            if (form.DeleteAll)
            {
                ClientCore.CreateNewDatabase();
                ClientCore.Close();
                ClientCore.Initialize();
            }
            else
            {
                if (form.DeleteMessages)
                    ClientCore.ClearMessages();
                if (form.DeletePluginSettings)
                    ClientCore.ClearPluginSettings();
                if (form.DeleteGlobalSettings)
                    ClientCore.ResetGlobalSettings();

            }
        }

        private void commandExportDatabase_Executed(object sender, EventArgs e)
        {
            saveDatabaseDialog.FileName = "Database.xml";
            if (saveDatabaseDialog.ShowDialog(this) != DialogResult.OK)
                return;
            ClientCore.ExportDatabase(saveDatabaseDialog.FileName);

            string filename = saveMessageDialog.FileName;
        }

        private void commandImportDatabase_Executed(object sender, EventArgs e)
        {
            openDatabaseDialog .FileName = "Database.xml";
            if (openDatabaseDialog.ShowDialog(this) != DialogResult.OK)
                return;
            ClientCore.ImportDatabase(openDatabaseDialog.FileName);

            ClientCore.Close();
            ClientCore.Initialize();
        }

        private void commandConfigureFilters_Executed(object sender, EventArgs e)
        {
            commandConfigurePlugins.Execute();
        }

        #endregion


        #region Others

        private void MainForm_Load(object sender, EventArgs e)
        {
            ClientCore.ChannelChanged += new EventHandler(ClientCore_ChannelChanged);
            ClientCore.MessageChanged +=new MessageChangedEventHandler(ClientCore_MessageChanged);
            ClientCore.EditReply += new EditItemsEventHandler(ClientCore_EditReply);
            ClientCore.ErrorOccured += new ClientErrorEventHandler(ClientCore_ErrorOccured);
            configureUI();
            tasks = new Queue<Task>();
            pendingRemoveItems = new List<ListViewItem>();
            LoadGlobalSettings();
            RefreshChannelList();
        }

        void ClientCore_ErrorOccured(object sender, ClientEventEventArgs e)
        {
            ShowErrorMessage(e.ErrorMessage, e.Critical);
            this.labelCurrentWork.Text = idleText;
        }

        void ClientCore_EditReply(object sender, EditItemsEventArgs e)
        {
            

            MessageEditForm form = new MessageEditForm(e.ReplyItems);
            form.MdiParent = this;
            form.WindowState = FormWindowState.Maximized;
            if (e.Source == null)
                form.Text = "[" + "New Message".Translate() + "]";
            else
                form.Text = "Re:" + "[" + e.Source.Title + "]"; ;
            form.EditCompleted += delegate
            {
                PendTask(new Task(delegate
                    {
                        this.Invoke(new Task(
                           delegate
                           {
                               labelCurrentWork.Text = "Posting message ".Translate() + "...";
                           }));

                        ClientCore.ReplyDone(e.Channel,e.Source,form.InputItems,e.Tag);
                        if (e.Source != null)
                            ClientCore.RefreshMessage(e.Source);
                        this.Invoke(new Task(
                           delegate
                           {
                               labelCurrentWork.Text = idleText;
                           }));
                        RefreshTreeViewUnreadNumber();
                        RefreshMessageList();
                    }));

            };
            form.Show();
        }

        private void PendTask(Task task)
        {
            tasks.Enqueue(task);
            Monitor.Enter(backgroundWorker);
            if (!backgroundWorker.IsBusy)
                backgroundWorker.RunWorkerAsync();
            menuCancelBackgroundJobs.Enabled = (tasks.Count != 0);
            Monitor.Exit(backgroundWorker);
        }

        private void configureUI()
        {
            this.RibbonControl.Font = SystemFonts.MenuFont;
            this.statusBar.Font = SystemFonts.StatusFont;
            this.comboListMode.Font = SystemFonts.MenuFont;
            this.tabStrip1.Font = SystemFonts.CaptionFont;
            this.tabStrip1.SelectedTabFont = new Font(this.tabStrip1.Font, FontStyle.Bold);
            this.comboListMode.SelectedItem = comboItemListAll;
            this.contextMenuBar.Font = SystemFonts.MenuFont;
            messagesListView.Columns.Add("Title", "Title".Translate());
            messagesListView.Columns.Add("Author", "Author".Translate());
            messagesListView.Columns.Add("PubTime", "Publish Time".Translate());
            messagesListView.ListViewItemSorter = new MessageListPubTimeSorter();
            messagesListView.Sorting = SortOrder.Descending;
        }

        private void menuMainUpdate_ExpandChange(object sender, EventArgs e)
        {
            if (menuUpdate.Expanded)
            {
                this.menuUpdate.PopupLocation = this.recentItemsContainer.DisplayRectangle.Location;
                this.menuUpdate_Popup.MinimumSize = this.recentItemsContainer.Size;
            }

        }


        private void navagationPane_ExpandedChanged(object sender, DevComponents.DotNetBar.ExpandedChangeEventArgs e)
        {
            this.splitter1.Visible = this.navagationPane.Expanded;
        }

        #endregion

        private void ClientCore_ChannelChanged(object sender, EventArgs e)
        {
            RefreshChannelList();
        }

        private void RefreshChannelList()
        {
            this.Invoke(new Task(
                delegate
                {
                    this.channelsTreeViewNormal.BeginUpdate();

                    RefreshChannelSubList(channelsTreeViewNormal.Nodes["treeNodeNormalRoot"], false);
                    this.channelsTreeViewNormal.EndUpdate();
                    this.channelsTreeViewSpam.BeginUpdate();
                    RefreshChannelSubList(channelsTreeViewSpam.Nodes["treeNodeSpamRoot"], true);
                    this.channelsTreeViewSpam.EndUpdate();

                    OpenTreeNode();
                }));

        }

        private void RefreshChannelSubList(TreeNode root,bool spam)
        {
            HashSet<string> groups = new HashSet<string>();
            HashSet<string> channels = new HashSet<string>();
            foreach (IChannel ch in ClientCore.GetChannels())
            {

                TreeNode parent = null;
                TreeNode[] parents = root.Nodes.Find(ch.Category, false);
                if (!groups.Contains(ch.Category))
                    groups.Add(ch.Category);
                if (!channels.Contains(ch.ComputeHash().ToString("X8")))
                    channels.Add(ch.ComputeHash().ToString("X8"));

                if (parents.Length == 0)
                {
                    parent = new TreeNode();
                    parent = root.Nodes.Add(ch.Category, ch.Category, 0);
                    parent.Tag = ch.Category;
                }
                else
                {
                    parent = parents[0];
                }

                TreeNode nodeChannel = null;
                TreeNode[] nodeChannels = parent.Nodes.Find(ch.ComputeHash().ToString("X8"), false);
                if (nodeChannels.Length == 0)
                {
                    nodeChannel = parent.Nodes.Add(ch.ComputeHash().ToString("X8"), ch.Title, 0);
                    nodeChannel.Tag = ch;
                }
                else
                {
                    
                    nodeChannel = nodeChannels[0];
                }

                HashSet<string> categoryHashes = new HashSet<string>();
                foreach (string str in ClientCore.GetChannelCategories(ch))
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        categoryHashes.Add(str);
                    }
                    TreeNode nodeCategory = null;
                    if (string.IsNullOrEmpty(str))
                        nodeCategory = nodeChannel;
                    else
                    {
                        TreeNode[] nodeCategories = null;
                        nodeCategories = nodeChannel.Nodes.Find(str, false);
                        if (nodeCategories.Length == 0)
                        {
                            nodeCategory = nodeChannel.Nodes.Add(str, str, 0);
                            if (!string.IsNullOrEmpty(str))
                                nodeCategory.Tag = str;
                        }
                        else
                        {
                            nodeCategory = nodeCategories[0];
                        }
                    }

                }
                foreach (TreeNode node in nodeChannel.Nodes.Cast<TreeNode>().ToArray())
                {
                    if (!categoryHashes.Contains(node.Name))
                        node.Remove();
                }

            }

            foreach (TreeNode node in root.Nodes.Cast<TreeNode>().ToArray())
            {
                if (!groups.Contains(node.Name))
                    node.Remove();
            }

            foreach (TreeNode groupnode in root.Nodes)
            {
                foreach (TreeNode node in groupnode.Nodes.Cast<TreeNode>().ToArray())
                {
                    if (!channels.Contains(node.Name))
                        node.Remove();
                }
            }

            RefreshTreeViewUnreadNumber(spam);
            this.channelsTreeViewNormal.EndUpdate();
        }

        private void OpenTreeNode()
        {
            TreeNode selectedNode = null;
             bool spam = false;
             if (navagationPane.SelectedPanel == paneViewNormal)
             {
                 selectedNode = channelsTreeViewNormal.SelectedNode;
                 spam = false;
             }
             else
             {
                 selectedNode = channelsTreeViewSpam.SelectedNode;
                 spam = true;
             }
            if (selectedNode == null)
            {
                currentMessageList = new IMessage[0];
            }
            else
            {
                IChannel ch;
                switch (selectedNode.Level)
                {
                    case 0:
                        currentMessage = null;
                        currentMessageList = emptyMessageList;
                        break;
                    case 1:
                        currentMessage = null;
                        currentMessageList = emptyMessageList;
                        break;
                    case 2:
                        ch = selectedNode.Tag as IChannel;
                        currentMessageList = (from message in ClientCore.GetMessageHeaders(ch, null)
                                              where message.Spam == spam
                                              select message).ToArray();
                        break;
                    case 3:
                        ch = selectedNode.Parent.Tag as IChannel;
                        currentMessageList = (from message in ClientCore.GetMessageHeaders(ch, selectedNode.Tag as string)
                                              where message.Spam == spam
                                              select message).ToArray();
                        break;
                    default:
                        break;
                }
            }

            RefreshMessageList();
        }

        private void ClientCore_MessageChanged(object sender, MessageChangedEventArgs e)
        {
            if (currentMessage != null && currentMessage.Id == e.Header.Id)
                RefreshMessageView();
 
            //不下载垃圾信息的附件 
            if (autoDownload && !e.Header.Spam)
                DownloadAttachments(e.Header,false);
        }
        private void DownloadAttachments(IMessage header,bool force)
        {

            IMessage msgHdr = header;

            PendTask(new Task(delegate
                {
                    IMessage msg = ClientCore.GetMessage(msgHdr);
                    if (msg == null)
                        return;

                    foreach (IFileObject attc in msg.Attachments)
                    {
                        if (!force && attc.FileSize > autoDownloadSizeLimit)
                            continue;
                        if (!force && System.IO.File.Exists(attc.LocalPath))
                            continue;
                        this.Invoke(new Task(delegate
                            {
                                this.labelCurrentWork.Text = "Downloading attachment ".Translate()+"\"" + attc.Filename + "\" ...";
                            }));
                        ClientCore.DownloadAttachment(msg, attc);
                        this.Invoke(new Task(delegate
                            {
                                this.labelCurrentWork.Text = idleText;
                            }));
                        if (currentMessage != null && currentMessage.Id == msg.Id)
                            RefreshMessageView();
                    }
                }));
        }
        private void RefreshMessageList()
        {
            this.Invoke(new Task(
                delegate
                {
                    IMessage[] messages = currentMessageList;
                    this.messagesListView.BeginUpdate();
                    try
                    {

                        HashSet<string> categories = new HashSet<string>();
                        foreach (IMessage message in messages)
                        {
                            if (!categories.Contains(message.Category))
                                categories.Add(message.Category);
                        }
       
                        RefreshMessageListGroups(categories);
                        RefreshMessageListItems(messages);
                        RefreshMessageListUnreadMark();
                    }
                    catch {
                    }
                    finally
                    {
                        this.messagesListView.EndUpdate();

                    }
                }));
        }

        private void RefreshMessageListUnreadMark()
        {
            this.Invoke(new Task(delegate
                {
                    foreach (ListViewItem item in messagesListView.Items)
                    {


                        IMessage message = ClientCore.GetMessage(item.Tag as IMessage);
                        if (comboListMode.SelectedItem == comboItemListAll)
                        {
                            if (message.Read)
                            {
                                item.ImageIndex = 0;
                                //item.ForeColor = messagesListView.ForeColor;
                                item.Font = new Font(messagesListView.Font, FontStyle.Regular);
                            }
                            else
                            {
                                item.Font = new Font(messagesListView.Font, FontStyle.Bold);
                                //tem.ForeColor = Color.Red;
                                item.ImageIndex = 1;
                            }

                        }
                        else
                        {
                            item.ImageIndex = 1;
                            item.Font = new Font(messagesListView.Font, FontStyle.Regular);
                        }
                    }
                }));

        }


        private void RefreshMessageListItems(IEnumerable<IMessage> messages)
        {
            if (comboListMode.SelectedItem == comboItemListAll)
            {
                HashSet<string> messageHashes = new HashSet<string>();
                foreach (IMessage msg in messages)
                {
                    messageHashes.Add(msg.ComputeHash().ToString("X8"));
                }

                foreach (IMessage message in messages)
                {
                  
                    string hashStr = message.ComputeHash().ToString("X8");
                    if (!messagesListView.Items.ContainsKey(hashStr))
                    {
                        ListViewItem item = null;
                        item = new ListViewItem();



                        item.Name = hashStr;
                        //item.SubItems.Add(message.Author);

                        item.Text = message.Title;
                        item.SubItems.Add(new ListViewItem.ListViewSubItem(item, message.PubTime.ToString()) { Name = "PubTime" });

                        if (message.Category == "" || message.Category == null)
                            item.Group = null;
                        else
                            item.Group = messagesListView.Groups[message.Category];

                        item.Tag = message;

                        messagesListView.Items.Add(item);
                    }
                }
                var items = messagesListView.Items.Cast<ListViewItem>().ToArray();
                foreach (ListViewItem item in items)
                {
                    if (!messageHashes.Contains(item.Name))
                        item.Remove();
                }
            }
            else
            {
                HashSet<string> messageHashes = new HashSet<string>();
                foreach (IMessage msg in messages)
                {
                    if (msg.Read)
                        continue;
                    messageHashes.Add(msg.ComputeHash().ToString("X8"));
                }

                foreach (IMessage message in messages)
                {
                    if (message.Read)
                        continue;

                    if (!messagesListView.Items.ContainsKey(message.ComputeHash().ToString("X8")))
                    {
                        ListViewItem item = new ListViewItem();
                        item.Name = message.ComputeHash().ToString("X8");
                        // item.SubItems.Add(message.Author);
                        item.Text = message.Title;
                        item.SubItems.Add(new ListViewItem.ListViewSubItem(item, message.PubTime.ToString()) { Name = "PubTime" });


                        if (message.Category == "" || message.Category == null)
                            item.Group = null;
                        else
                            item.Group = messagesListView.Groups[message.Category];

                        item.Tag = message;

                        messagesListView.Items.Add(item);
                    }

                }
                var items = messagesListView.Items.Cast<ListViewItem>().ToArray();
                foreach (ListViewItem item in items)
                {
                    if (!messageHashes.Contains(item.Name))
                        messagesListView.Items.Remove(item);
                }
            }
        }

        private void RefreshMessageListGroups(HashSet<string> categories)
        {
            foreach (string category in categories)
            {
                ListViewGroup group = new ListViewGroup(category, category);
                if (!messagesListView.Groups.Contains(group))
                    messagesListView.Groups.Add(group);
            }
            var groups = messagesListView.Groups.Cast<ListViewGroup>().ToArray();
            foreach (ListViewGroup group in groups)
            {
                if (!categories.Contains(group.Header))
                    messagesListView.Groups.Remove(group);
            }
        }
        private void RefreshTreeViewUnreadNumber()
        {
            RefreshTreeViewUnreadNumber(true);
            RefreshTreeViewUnreadNumber(false);
        }

        private void RefreshTreeViewUnreadNumber(bool spam)
        {
            this.Invoke(new Task(
                delegate
                {
                    int nTotal = 0;
                    TreeNode rootNode = null;

                    if (spam)
                    {
                        channelsTreeViewSpam.BeginUpdate();
                        rootNode = channelsTreeViewSpam.Nodes["treeNodeSpamRoot"];
                    }
                    else
                    {
                        channelsTreeViewNormal.BeginUpdate();
                        rootNode = channelsTreeViewNormal.Nodes["treeNodeNormalRoot"];
                    }

                    int nRoot = 0;
                    foreach (TreeNode groupNode in rootNode.Nodes)
                    {
                        int nGroup = 0;
                        foreach (TreeNode channelNode in groupNode.Nodes)
                        {
                            int nChannel = 0;
                            foreach (TreeNode categoryNode in channelNode.Nodes)
                            {
                                int nCategory = ClientCore.GetUnreadNumber(channelNode.Tag as IChannel, categoryNode.Tag as string, spam);
                                if (nCategory > 0)
                                {
                                    categoryNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Bold);
                                    categoryNode.Text = categoryNode.Tag as string + "(" + nCategory.ToString() + ")";
                                }
                                else
                                {
                                    categoryNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Regular);
                                    categoryNode.Text = categoryNode.Tag as string;

                                }
                                nChannel += nCategory;
                            }

                            //ReplyItems without category
                            nChannel += ClientCore.GetUnreadNumber(channelNode.Tag as IChannel, string.Empty, spam);

                            if (nChannel > 0)
                            {
                                channelNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Bold);
                                channelNode.Text = (channelNode.Tag as IChannel).Title + "(" + nChannel.ToString() + ")";
                            }
                            else
                            {
                                channelNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Regular);
                                channelNode.Text = (channelNode.Tag as IChannel).Title;

                            }
                            nGroup += nChannel;
                        }
                        if (nGroup > 0)
                        {
                            groupNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Bold);
                            groupNode.Text = groupNode.Tag as string + "(" + nGroup.ToString() + ")";
                        }
                        else
                        {
                            groupNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Regular);
                            groupNode.Text = groupNode.Tag as string;

                        }
                        nRoot += nGroup;

                    }
                    if (nRoot > 0)
                    {
                        rootNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Bold);
                        rootNode.Text = rootNode.Tag as string + "(" + nRoot.ToString() + ")";
                    }
                    else
                    {
                        rootNode.NodeFont = new Font(channelsTreeViewNormal.Font, FontStyle.Regular);
                        rootNode.Text = rootNode.Tag as string;

                    }
                    if (spam)
                    {
                        channelsTreeViewSpam.EndUpdate();
                    }
                    else
                    {
                        channelsTreeViewNormal.EndUpdate();
                    }

                    if (!spam)
                        labelUnreadMessages.Text = (nRoot.ToString() + labelUnreadMessages.Tag as string);
                }));
        }


        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            commandExitApplication.Execute();
        }

        private void channelsTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            OpenTreeNode();
        }

        private void messagesListView_Resize(object sender, EventArgs e)
        {
            messagesListView.TileSize = new Size(this.messagesListView.ClientSize.Width, messagesListView.TileSize.Height);
        }


        private void RefreshMessageView()
        {
            this.Invoke(new Task(
                delegate
                {

                    //TODO: Show message
                    if (currentMessage == null)
                    {
                        messageViewer.Hide();
                    }
                    else
                    {
                        messageViewer.MdiParent = this;

                        IMessage message = ClientCore.GetMessage(currentMessage);
                        messageViewer.ShowMessage(ClientCore.GetViewer(message.ContentType), message);
                        messageViewer.WindowState = FormWindowState.Maximized;
                        messageViewer.Show();
                        this.RibbonControl.Refresh();
                    }
                }));
        }

        private void messageViewer_AttachmentLinkClicked(object sender, AttachmentLinkClickedEventArgs e)
        {
            IFileObject attachment = e.Attachment;
            IViewer viewer = ClientCore.GetViewer(attachment.FileType);
            
            AttachmentOpenDialog dlg = new AttachmentOpenDialog();
            dlg.CanOpen = (viewer != null);
            dlg.FileName = e.Attachment.Filename;
            bool needDownload = System.IO.File.Exists(attachment.LocalPath);
            switch (dlg.ShowDialog())
            {
                case DialogResult.Yes:
                    {
                            IMessage message = currentMessage;

                            System.IO.Stream stream = ClientCore.CreateAttachmentStream(e.Attachment);

                            if (stream != null)
                            {
                                this.Invoke(new Task(delegate
                                {
                                    DocumentViewerForm doc =  new DocumentViewerForm();
                                    doc.MdiParent = this;
                                    doc.Text = message.Title + " - " + e.Attachment.Filename;
                                    doc.WindowState = FormWindowState.Maximized;
                                    doc.Show();
                                    doc.ShowDocument(viewer,e.Attachment.FileType, stream);
                                }));
                                return;
                            }


                            this.PendTask(new Task(
                                delegate
                                {
                                    this.Invoke(new Task(
                                        delegate
                                        {
                                            labelCurrentWork.Text = "Downloading attachment ".Translate() + "\"" + attachment.Filename + "\" ...";
                                        }));
                                    ClientCore.DownloadAttachment(message, attachment);
                                    stream = ClientCore.CreateAttachmentStream(attachment);
                                    RefreshMessageView();
                                    this.Invoke(new Task(
                                       delegate
                                       {
                                           labelCurrentWork.Text = idleText;
                                       }));
                                    if (stream == null)
                                    {
                                         return;
                                    }

                                    this.Invoke(new Task(delegate
                                    {
                                        DocumentViewerForm doc = new DocumentViewerForm();
                                        doc.Text = message.Title + " - " + e.Attachment.Filename;
                                        doc.MdiParent = this;
                                        doc.WindowState = FormWindowState.Maximized;
                                        doc.Show();
                                        doc.ShowDocument(viewer,e.Attachment.FileType, stream);
                                    }));
                                }));
                    }
                    break;
                case DialogResult.No:
                    {
                        saveAttachmentDialog.FileName = e.Attachment.Filename;
                        saveAttachmentDialog.Filter = "*." + e.Attachment.FileType + "|" + e.Attachment.FileType;
                        saveAttachmentDialog.AddExtension = true;
                        if (saveAttachmentDialog.ShowDialog() == DialogResult.OK)
                        {
                            IMessage message = currentMessage;

                            string targetFileName = saveAttachmentDialog.FileName;
                            System.IO.Stream stream = ClientCore.CreateAttachmentStream(e.Attachment);
                            if (stream != null)
                            {
                                try
                                {

                                    System.IO.Stream target = System.IO.File.Create(targetFileName);

                                    byte[] buffer = new byte[1024];
                                    int nTotle = 0;
                                    while (true)
                                    {
                                        int nRead = stream.Read(buffer, 0, 1024);
                                        if (nRead == 0)
                                            break;
                                        nTotle += nRead;
                                        target.Write(buffer, 0, nRead);
                                    }
                                    target.Close();
                                }
                                catch
                                {
                                    MessageBox.Show(this, "Cannot open attachment file.".Translate(), "Error".Translate(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    return;
                                }
                                finally
                                {
                                    stream.Close();
                                    this.Invoke(new Task(
                                        delegate
                                        {
                                            labelCurrentWork.Text = idleText;
                                        }));
                                }
                                return;
                            }


                            this.PendTask(new Task(
                                delegate
                                {
                                    stream = ClientCore.CreateAttachmentStream(e.Attachment);
                                    this.Invoke(new Task(
                                        delegate
                                        {
                                            labelCurrentWork.Text = "Downloading attachment ".Translate() + "\"" + attachment.Filename + "\" ...";
                                        }));
                                    if (stream == null)
                                    {
                                        ClientCore.DownloadAttachment(message, attachment);
                                        stream = ClientCore.CreateAttachmentStream(attachment);
                                    }

                                    RefreshMessageView();
                                    if (stream == null)
                                    {
                                        this.Invoke(new Task(delegate
                                        {
                                            MessageBox.Show(this, "Cannot open attachment file.".Translate(), "Error".Translate(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                                            labelCurrentWork.Text = idleText;
                                        }));
                                        return;
                                    }

                                    try
                                    {

                                        System.IO.Stream target = System.IO.File.Create(targetFileName);

                                        byte[] buffer = new byte[1024];
                                        int nTotle = 0;
                                        while (true)
                                        {
                                            int nRead = stream.Read(buffer, 0, 1024);
                                            if (nRead == 0)
                                                break;
                                            nTotle += nRead;
                                            target.Write(buffer, 0, nRead);
                                        }
                                        target.Close();
                                    }
                                    catch
                                    {
                                        MessageBox.Show(this, "Cannot open attachment file.".Translate(), "Error".Translate(), MessageBoxButtons.OK, MessageBoxIcon.Error);
                                        return;
                                    }
                                    finally
                                    {
                                        stream.Close();
                                        this.Invoke(new Task(
                                            delegate
                                            {
                                                labelCurrentWork.Text = idleText;
                                            }));
                                    }
                                }));
                        }
                    }
                    break;
                case DialogResult.Cancel:
                    break;
                default:
                    break;

            }

        }

        void form_PluginInfoChanged(object sender, PluginInfoChangedEventArgs e)
        {
            ClientCore.SetPluginInformation(e.Information);
            pluginManagementDialog.PluginList = ClientCore.GetPlugins();
            RefreshChannelList();
        }

        void form_PluginRemoveRequested(object sender, PluginRemoveRequestedEventArgs e)
        {
            ClientCore.DeletePlugin(e.Information);
            pluginManagementDialog.PluginList = ClientCore.GetPlugins();
            RefreshChannelList();
        }

        void form_PluginConfigRequested(object sender, PluginConfigRequestedEventArgs e)
        {
            ClientCore.ConfigPlugin(e.Information);
            pluginManagementDialog.PluginList = ClientCore.GetPlugins();
            RefreshChannelList();
        }

        void form_PluginInstallRequested(object sender, PluginInstallRequestedEventArgs e)
        {
            ClientCore.AddPlugin(e.AssemblyPath);
            pluginManagementDialog.PluginList = ClientCore.GetPlugins();
            RefreshChannelList();
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Monitor.Enter(tasks);
            Task task = null;

            try
            {
                if (backgroundWorker.CancellationPending)
                {
                    tasks.Clear();
                    return;
                }
                task = tasks.Dequeue();
            }
            catch
            {
            }
            finally
            {
                Monitor.Exit(tasks);
            }

            try
            {
                task.Invoke();
            }
            catch (ObjectDisposedException)
            {
            }
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Monitor.Enter(backgroundWorker);
            Monitor.Enter(tasks);
            menuCancelBackgroundJobs.Enabled = (tasks.Count != 0);
            if (tasks.Count == 0)
            {
                Monitor.Exit(tasks);
                Monitor.Exit(backgroundWorker);
                return;
            }
            Monitor.Exit(tasks);
            backgroundWorker.RunWorkerAsync();
            Monitor.Exit(backgroundWorker);
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        private void timerCurrentWorkAnnimate_Tick(object sender, EventArgs e)
        {

                animationIndex++;
                if (animationIndex >= imagesCurrentWorkAnimaion.Images.Count)
                    animationIndex = 0;
                buttonCurrentWork.ImageIndex = animationIndex;
            
        }

        private void comboListMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshMessageList();
        }

        private void messagesListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (!e.IsSelected)
            {
                if (comboListMode.SelectedItem == comboItemListAll)
                {

                }
                else
                {

                    pendingRemoveItems.Add(e.Item);
                    timerRemoveItemDelay.Start();
                }
            }
            else
            {


                IMessage messageHeader = e.Item.Tag as IMessage;
                currentMessage = messageHeader;
                MarkAsRead(messageHeader);

                channelsTreeViewNormal.BeginUpdate();
                channelsTreeViewSpam.BeginUpdate();
                RefreshTreeViewUnreadNumber();
                channelsTreeViewNormal.EndUpdate();
                channelsTreeViewSpam.EndUpdate();

                messagesListView.BeginUpdate();
                RefreshMessageListUnreadMark();
                messagesListView.EndUpdate();

                RefreshMessageView();

            }
        }

        private void timerRemoveItemDelay_Tick(object sender, EventArgs e)
        {
            try
            {
                foreach (ListViewItem item in pendingRemoveItems)
                    item.Remove();
                pendingRemoveItems.Clear();

            }
            catch
            {
            }
            finally
            {
                timerRemoveItemDelay.Stop();
            }
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void timerAutoRefresh_Tick(object sender, EventArgs e)
        {
            commandUpdateAllChannels.Execute();
        }

        private void MainForm_FontChanged(object sender, EventArgs e)
        {
            configureUI();
        }

        private void commandMarkAllRead_Executed(object sender, EventArgs e)
        {
            TreeNode selectedNode = null;

            if (navagationPane.SelectedPanel == paneViewNormal)
                selectedNode = channelsTreeViewNormal.SelectedNode;
            else
                selectedNode = channelsTreeViewSpam.SelectedNode;

            if (selectedNode == null)
                return;
            this.Invoke(new Task(
                   delegate
                   {

                       VisitTreeNode(selectedNode,new MessageVisitor(MarkAsRead));

                   }));
            RefreshTreeViewUnreadNumber();
            RefreshMessageList();

        }

        private delegate void MessageVisitor(IMessage header);

        private void MarkAsRead(IMessage header)
        {
            IMessage message = ClientCore.GetMessage(header);
             header.Read = true;
             if (!message.Read)
             {
                 message.Read = true;
                 ClientCore.UpdateMessage(message);
             }
        }
        private void DeleteMessage(IMessage header)
        {
            ClientCore.DeleteMessage(header);
        }
        private void VisitTreeNode(TreeNode node,MessageVisitor visitor)
        {
            bool spam = false;
            if (node.TreeView == channelsTreeViewNormal)
                spam = false;
            else
                spam = true;
  

            IChannel ch = null;
            IEnumerable<IMessage> headers;

            if (node == null)
                return;
            switch (node.Level)
            {
                case 0:
                    foreach (TreeNode childNode in node.Nodes)
                    {
                        VisitTreeNode(childNode,visitor);
                    }
                    break;
                case 1:
                    foreach (TreeNode childNode in node.Nodes)
                    {
                        VisitTreeNode(childNode,visitor);
                    }
                    break;
                case 2:
                    ch = node.Tag as IChannel;
                    headers = ClientCore.GetMessageHeaders(ch, null);
                    foreach (IMessage header in headers)
                    {
                        if (spam == header.Spam)
                            visitor.Invoke(header);
                    }
                    break;
                case 3:
                    ch = node.Parent.Tag as IChannel;
                    headers = ClientCore.GetMessageHeaders(ch, node.Tag as string);
                    foreach (IMessage header in headers)
                    {
                        if (spam == header.Spam)
                            visitor.Invoke(header);
                    }
                    break;
                default:
                    break;
            }

        }

        private void commandDeleteAll_Executed(object sender, EventArgs e)
        {
            TreeNode selectedNode = null;
            if (navagationPane.SelectedPanel == paneViewNormal)
                selectedNode = channelsTreeViewNormal.SelectedNode;
            else
                selectedNode = channelsTreeViewSpam.SelectedNode;
            if (selectedNode == null)
                return;
            if (MessageBox.Show(this, "Are you sure to delete all messages of ".Translate() + selectedNode.Text + "?", "iHunter".Translate(), MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                return;
            this.Invoke(new Task(
                     delegate
                     {
                         VisitTreeNode(selectedNode, new MessageVisitor(DeleteMessage));
                     }));
            RefreshTreeViewUnreadNumber();
            OpenTreeNode();
            RefreshMessageList();
        }

        private void commandCleanDatabase_Executed(object sender, EventArgs e)
        {
            ClientCore.CleanDatabase();
            MessageBox.Show(this, "Database is cleaned!".Translate(), "iHunter".Translate(), MessageBoxButtons.OK, MessageBoxIcon.Information);
            RefreshMessageList();

        }

        private void commandUpdateSelectedItem_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            IMessage header = currentMessage;
            PendTask(new Task(delegate
            {
                IMessage message = ClientCore.GetMessage(header);
                if (message == null)
                    return;
                this.Invoke(new Task(
                   delegate
                   {
                       labelCurrentWork.Text = "Updating message ".Translate()+" \"" + message.Title + "\" ...";
                   }));
                ClientCore.RefreshMessage(message);
                this.Invoke(new Task(
                   delegate
                   {
                       labelCurrentWork.Text = idleText;
                   }));
                RefreshTreeViewUnreadNumber();
                RefreshMessageListUnreadMark();
                if (autoDownload && !header.Spam)
                    DownloadAttachments(message, false);
            }));
        }

        private void sliderRankSet_ValueChanged(object sender, EventArgs e)
        {
            XmlDocument settings = ClientCore.GetGlobalSettings();
            settings.DocumentElement["Rank"].InnerText = sliderRankSet.Value.ToString();
            ClientCore.SetGlobalSettings(settings);
            editRankValueInput.Value = sliderRankSet.Value;
        }

        private void ribbonButtonRank_ExpandChange(object sender, EventArgs e)
        {
            XmlDocument settings = ClientCore.GetGlobalSettings();
            if (ribbonButtonRank.Expanded)
            {
                sliderRankSet.Value = int.Parse(settings.DocumentElement["Rank"].InnerText);
                editRankValueInput.Text = settings.DocumentElement["Rank"].InnerText;

            }
        }
        private void editRankValueInput_ValueChanged(object sender, EventArgs e)
        {
            XmlDocument settings = ClientCore.GetGlobalSettings();
            settings.DocumentElement["Rank"].InnerText = editRankValueInput.Value.ToString();
            ClientCore.SetGlobalSettings(settings);
            sliderRankSet.Value = editRankValueInput.Value;

        }

        private void labelCurrentWork_TextChanged(object sender, EventArgs e)
        {
            if (labelCurrentWork.Text.Length == 0 || labelCurrentWork.Text == idleText)
            {
                buttonCurrentWork.ImageIndex = 0;
                timerCurrentWorkAnnimate.Stop();
            }
            else
                timerCurrentWorkAnnimate.Start();
        }

        private void commandCancelBackgroundJobs_Executed(object sender, EventArgs e)
        {
            Monitor.Enter(tasks);
            tasks.Clear();
            Monitor.Exit(tasks);
        }

        private void channelsTreeViewNormal_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            channelsTreeViewNormal.SelectedNode = e.Node;
        }

        private void commandPostNewMessage_Executed(object sender, EventArgs e)
        {
            TreeNode selectedNode = null;
            if (navagationPane.SelectedPanel == paneViewNormal)
                selectedNode = channelsTreeViewNormal.SelectedNode;
            else
                selectedNode = channelsTreeViewSpam.SelectedNode;

            if (selectedNode == null)
                return;

            IChannel channel = null;
            
            if (selectedNode.Level == 2)
                channel = selectedNode.Tag as IChannel;
            else if (selectedNode.Level == 3)
                channel = selectedNode.Parent.Tag as IChannel;
            
            if (channel == null)
                return;
            
            ClientCore.BeginPost(channel);
                
        }

        private void commandDownloadAttachments_Executed(object sender, EventArgs e)
        {
            if (currentMessage == null)
                return;
            DownloadAttachments(currentMessage, true);
        }





    }

    public static class TranlateHelperExtension
    {
        private static TranslateHelperList translateList;
        static TranlateHelperExtension()
        {
            translateList = new TranslateHelperList();
        }
        public static string Translate(this string str)
        {
            string translate = str;
            //translateList.Invoke(new Task(delegate
           //     {
                    var result = from item in translateList.Items.Cast<ListViewItem>()
                                 where item.Text == str
                                 select item;
                    
                    ListViewItem transItem = null;
                    if (result.Count() != 0)
                        transItem = result.First();

                    if (transItem != null && transItem.SubItems.Count >=2)
                        translate = transItem.SubItems[1].Text;

               // }));
            if (string.IsNullOrEmpty(translate))
                return str;
            else
                return translate;
        }
    }
}
